/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.ipti.br.tag.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author root
 */
public class CalendarUtil {

    private static final DateFormat dateFormat;
    private static final DateFormat dateFormatTimestamp;
    private static final DateFormat dateFormatTime;
    private static final DateFormat dateFormatText;

    static {
        dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormatTimestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSS");
        dateFormatTime = new SimpleDateFormat("HH:mm:ss:SSSS");
        dateFormatText = new SimpleDateFormat("dd/MM/yyyy");
    }

    public static String getFormatedTime(Calendar date) {
        String dateAux;
        if (date == null) {
            dateAux = "";
        } else {
            dateAux = dateFormatTime.format(date.getTime());
        }
        return dateAux;
    }
    
    public static String getFormatedDate(Calendar date) {
        String dateAux;
        if (date == null) {
            dateAux = "";
        } else {
            dateAux = dateFormat.format(date.getTime());
        }
        return dateAux;
    }
    
    public static String getFormatedText(Calendar date) {
        String dateAux;
        if (date == null) {
            dateAux = "";
        } else {
            dateAux = dateFormatText.format(date.getTime());
        }
        return dateAux;
    }
    
    public static String getFormatedDate(Date date) {
        String dateAux;
        if (date == null) {
            dateAux = "";
        } else {
            dateAux = dateFormatText.format(date);
        }
        return dateAux;
    }

    public static Calendar convertToDate(String s) {
        Calendar str = Calendar.getInstance();
        try {
            str.setTime(dateFormat.parse(s));
        } catch (ParseException ex) {
            Logger.getLogger(CalendarUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return str;
    }

    public static String getFormatedDateTimestamp(Calendar date) {
        return dateFormatTimestamp.format(date.getTime());
    }

    public static Calendar convertToTimestamp(String s) {
        Calendar str = Calendar.getInstance();
        try {
            str.setTime(dateFormatTimestamp.parse(s));
        } catch (ParseException ex) {
            Logger.getLogger(CalendarUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return str;
    }

    public static List<Calendar> getArrayBetweenValues(Calendar initialDate, Calendar finalDate) {
        if (finalDate.get(Calendar.YEAR) > initialDate.get(Calendar.YEAR)) {
            int isLeapYearCount = 0;
            for (int i = initialDate.get(Calendar.YEAR); i < finalDate.get(Calendar.YEAR); i++) {
                if (isBissexto(i)) {
                    isLeapYearCount += 1;
                }
            }
            int aux = finalDate.get(Calendar.DAY_OF_YEAR) + (365 * (finalDate.get(Calendar.YEAR) - initialDate.get(Calendar.YEAR))) + isLeapYearCount;
            List<Calendar> array = new ArrayList<Calendar>();
            for (int i = initialDate.get(Calendar.DAY_OF_YEAR); i <= aux; i++) {
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.YEAR, initialDate.get(Calendar.YEAR));
                calendar.set(Calendar.DAY_OF_YEAR, i);
                calendar.setTime(calendar.getTime());
                array.add(calendar);
            }
            return array;
        } else {
            List<Calendar> array = new ArrayList<Calendar>();
            for (int i = initialDate.get(Calendar.DAY_OF_YEAR); i <= finalDate.get(Calendar.DAY_OF_YEAR); i++) {
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.YEAR, initialDate.get(Calendar.YEAR));
                calendar.set(Calendar.DAY_OF_YEAR, i);
                calendar.setTime(calendar.getTime());
                array.add(calendar);
            }
            return array;
        }
    }

    public static boolean isBissexto ( int year) {
      if ( year < 0 )
          return ((year + 1) & 3) == 0;
      if ( year < 1582 )
          return (year & 3) == 0;
      if ((year & 3) == 0 && year % 100 != 0 )
          return true;
      return ( year % 400 == 0 );
   }

    public static List<Calendar> disposeHolidayDates(List<Calendar> allDates, List<Calendar> holidayDates) {
        List<Calendar> mergedCalendar = new ArrayList<Calendar>();
        int i = 0;
        int j = 0;
        while (i < allDates.size() && j < holidayDates.size()) {
            if (allDates.get(i).get(Calendar.DAY_OF_YEAR) < holidayDates.get(j).get(Calendar.DAY_OF_YEAR)) {
                mergedCalendar.add(allDates.get(i));
                i++;
            } else {
                if (allDates.get(i).get(Calendar.DAY_OF_YEAR) > holidayDates.get(j).get(Calendar.DAY_OF_YEAR)) {

                    j++;
                } else {
                    i++;
                    j++;
                }
            }
        }
        if (i < allDates.size()) {
            while (i < allDates.size()) {
                mergedCalendar.add(allDates.get(i));
                i++;
            }
        } else {
        }
        return mergedCalendar;
    }

     public static List<Calendar> disposeHolidayDates2(List<Calendar> allDates, List<Calendar> holidayDates) {
          List<Calendar> mergedCalendar = new ArrayList<Calendar>();
        int i = 0;
        int j = 0;

        while (i < allDates.size() && j < holidayDates.size()) {

            //recalculates all fieds in order to compare
            holidayDates.get(j).setTime(holidayDates.get(j).getTime());
            allDates.get(i).setTime(allDates.get(i).getTime());

            //if (allDates.get(i).before(holidayDates.get(j)))
            //if(allDates.get(i).compareTo(holidayDates.get(i))<0)
            if(compareDates(allDates.get(i), holidayDates.get(j)) < 0)
            {
                //System.out.println("a");
                //mergedCalendar.add(allDates.get(i));
                i++;
            }
            else
            {
                //if (allDates.get(i).after(holidayDates.get(j)))
                //if(allDates.get(i).compareTo(holidayDates.get(i))>0)
                if(compareDates(allDates.get(i), holidayDates.get(j)) > 0)
                {
                   // System.out.println("b");
                   // System.out.println("j:"+holidayDates.get(j));
                   // System.out.println("i:"+allDates.get(i));
                  //  System.out.println();
                    j++;
                }
                else
                {

                    //if(allDates.get(i).compareTo(holidayDates.get(i))==0){
                    if(compareDates(allDates.get(i), holidayDates.get(j)) == 0){
                      //  System.out.println("c");
                        allDates.remove(i);
                        j++;
                    }
                }//else
            }//else
        }
        return allDates;
    }

      public static int compareDates(Calendar cal1, Calendar cal2)
      {
          if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR))
            return -1;
          else
              if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR))
                 return 1;
              else
                  if (cal1.get(Calendar.DAY_OF_YEAR) < cal2.get(Calendar.DAY_OF_YEAR))
                      return -1;
                  else
                      if (cal1.get(Calendar.DAY_OF_YEAR) > cal2.get(Calendar.DAY_OF_YEAR))
                          return 1;
                      else
                          return 0;
      }

}
